package org.mybatis.generator.plugins.view;

import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.GeneratedJavaScriptFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.OutputUtilities;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaElement;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.internal.util.StringUtility;


/**
 * 生成controller类 ,适用于ExtJS框架
 * 
 * super_dev_001
 */
public class MybatisControllerExtPlugin extends PluginAdapter {

	private FullyQualifiedJavaType slf4jLogger;
	private FullyQualifiedJavaType slf4jLoggerFactory;
	private FullyQualifiedJavaType controllerType;
	private FullyQualifiedJavaType interfaceType;
	private FullyQualifiedJavaType pojoType;
	private FullyQualifiedJavaType listType;
	private FullyQualifiedJavaType autowired;
	private FullyQualifiedJavaType controller;
	private FullyQualifiedJavaType requestMapping;
	private FullyQualifiedJavaType modelAttribute;
	private FullyQualifiedJavaType responseBody;
	private FullyQualifiedJavaType beanUtils;
	private FullyQualifiedJavaType needLogin;
	private FullyQualifiedJavaType baseResp;
	private FullyQualifiedJavaType pageList;
	private FullyQualifiedJavaType responseUtils;
	private FullyQualifiedJavaType commonUtil;
	private FullyQualifiedJavaType qoType;
	private FullyQualifiedJavaType boType;
	private FullyQualifiedJavaType paginationResp;
	private FullyQualifiedJavaType paginator;

	private FullyQualifiedJavaType abstractController;

	private FullyQualifiedJavaType returnType;
	private String targetPackage;
	private String servicePack;
	private String targetModel;
	private String platform;
	private String serviceName;
	private String controllerPack;
	private String project;
	private String pojoUrl;

	private List<Method> methods;
	/**
	 * 是否添加注解
	 */
	private boolean enableAnnotation = true;
	private boolean enableInsert = false;
	private boolean enableInsertSelective = false;
	private boolean enableDeleteByPrimaryKey = false;
	private boolean enableDeleteByExample = false;
	private boolean enableUpdateByExample = false;
	private boolean enableUpdateByExampleSelective = false;
	private boolean enableUpdateByPrimaryKey = false;
	private boolean enableUpdateByPrimaryKeySelective = false;

	public MybatisControllerExtPlugin() {
		super();
		// 默认是slf4j
		slf4jLogger = new FullyQualifiedJavaType("org.slf4j.Logger");
		slf4jLoggerFactory = new FullyQualifiedJavaType(
				"org.slf4j.LoggerFactory");
		methods = new ArrayList<Method>();
	}

	@Override
	public boolean validate(List<String> warnings) {
		if (StringUtility.stringHasValue(properties
				.getProperty("enableAnnotation")))
			enableAnnotation = StringUtility.isTrue(properties
					.getProperty("enableAnnotation"));

		targetPackage = properties.getProperty("targetPackage");
		targetModel = properties.getProperty("targetModel");
		platform = properties.getProperty("platform");
		servicePack = targetPackage  + "." + platform+ ".service." + targetModel;
		controllerPack = targetPackage + "." + platform + ".controller."
				+ targetModel;
		project = properties.getProperty("targetProject");

		pojoUrl = context.getJavaModelGeneratorConfiguration()
				.getTargetPackage();

		paginator= new FullyQualifiedJavaType(
				"com.github.miemiedev.mybatis.paginator.domain.Paginator");
		
		autowired = new FullyQualifiedJavaType(
				"org.springframework.beans.factory.annotation.Autowired");
		controller = new FullyQualifiedJavaType(
				"org.springframework.stereotype.Controller");
		requestMapping = new FullyQualifiedJavaType(
				"org.springframework.web.bind.annotation.RequestMapping");
		modelAttribute = new FullyQualifiedJavaType(
				"org.springframework.web.bind.annotation.ModelAttribute");
		responseBody = new FullyQualifiedJavaType(
				"org.springframework.web.bind.annotation.ResponseBody");
		beanUtils = new FullyQualifiedJavaType(
				"org.springframework.beans.BeanUtils");
		pageList = new FullyQualifiedJavaType(
				"com.github.miemiedev.mybatis.paginator.domain.PageList");
		baseResp = new FullyQualifiedJavaType(targetPackage+ "."+ platform
				+ ".model.vo.BaseResp");
		responseUtils = new FullyQualifiedJavaType(targetPackage+ "."+ platform
				+ ".utils.ResponseUtils");
		commonUtil = new FullyQualifiedJavaType(targetPackage+ "."+ platform
				+ ".commons.CommonUtils");
		abstractController = new FullyQualifiedJavaType(targetPackage + "."
				+ platform + ".controller.AbstractController");
		needLogin = new FullyQualifiedJavaType(targetPackage + "." + platform
				+ ".web.annotation.NeedLogin");
		paginationResp = new FullyQualifiedJavaType(targetPackage + ".model.resp.PaginationResp");
		
		return true;
	}

	@Override
	public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(
			IntrospectedTable introspectedTable) {
		List<GeneratedJavaFile> files = new ArrayList<GeneratedJavaFile>();
		String table = introspectedTable.getBaseRecordType();
		String tableName = table.replaceAll(this.pojoUrl + ".", "");
		tableName = util.StringUtils.replaceLast(tableName,"Po","");
		serviceName = toLowerCase(tableName + "Service");

		interfaceType = new FullyQualifiedJavaType(servicePack + "."
				+ tableName + "Service");
		controllerType = new FullyQualifiedJavaType(controllerPack + "."
				+ tableName + "Controller");

		pojoType = new FullyQualifiedJavaType(pojoUrl + "." + tableName + "Po");


		qoType = new FullyQualifiedJavaType(util.StringUtils.replaceLast(introspectedTable.getBaseRecordType().replace(".po.", ".qo."),"Po", "Qo"));

		listType = new FullyQualifiedJavaType("java.util.List");
		TopLevelClass topLevelClass = new TopLevelClass(controllerType);

		// 导入必要的类
		addImport(topLevelClass);

		// 实现类
		addController(topLevelClass, introspectedTable, tableName, files);

		addLogger(topLevelClass);
		return files;
	}

	/**
	 * 添加实现类
	 * 
	 * @param introspectedTable
	 * @param tableName
	 * @param files
	 */
	protected void addController(TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable, String tableName,
			List<GeneratedJavaFile> files) {
		topLevelClass.setVisibility(JavaVisibility.PUBLIC);

		// topLevelClass.addInnerClass(new
		// InnerClass("com.yici.mall.admin.web.controller.AbstractControllerd"));

		topLevelClass.setSuperClass(abstractController);
		topLevelClass.addImportedType(abstractController);

		if (enableAnnotation) {
			topLevelClass.addAnnotation("@Controller");
			topLevelClass.addImportedType(controller);

			topLevelClass.addAnnotation("@RequestMapping(\"/" + targetModel
					+ "/" + toLowerCase(tableName) + "\")");
			topLevelClass.addImportedType(requestMapping);

			// topLevelClass.addAnnotation("@NeedLogin");
			// topLevelClass.addImportedType(needLogin);

			topLevelClass.addImportedType(modelAttribute);
			topLevelClass.addImportedType(responseBody);
			topLevelClass.addImportedType(beanUtils);
		}
		// 添加引用dao
		addField(topLevelClass, tableName);
		// 添加方法
		addBaseMethod(topLevelClass, introspectedTable, tableName);
		/**
		 * type 的意义 pojo 1 ;key 2 ;example 3 ;pojo+example 4
		 */

		Method method = addExample(introspectedTable, tableName);
		addMethodComment(method, "添加记录");
		method.addAnnotation("@RequestMapping(value = \"add\")");
		method.addAnnotation("@ResponseBody");
		topLevelClass.addMethod(method);

		method = modifyExample(introspectedTable, tableName);
		addMethodComment(method, "修改记录");
		method.addAnnotation("@RequestMapping(value = \"modify\")");
		method.addAnnotation("@ResponseBody");
		topLevelClass.addMethod(method);

		method = batchModifyExample(introspectedTable, tableName);
		addMethodComment(method, "批量修改记录信息");
		method.addAnnotation("@RequestMapping(value = \"modifyByBatch\")");
		method.addAnnotation("@ResponseBody");

		method = deleteById(introspectedTable, tableName);
		addMethodComment(method, "根据主键删除记录");
		method.addAnnotation("@RequestMapping(value = \"deleteById\")");
		method.addAnnotation("@ResponseBody");
		topLevelClass.addMethod(method);

		method = deleteByBatch(introspectedTable, tableName);
		addMethodComment(method, "根据主键指删除记录");
		method.addAnnotation("@RequestMapping(value = \"deleteByBatch\")");
		method.addAnnotation("@ResponseBody");
		topLevelClass.addMethod(method);

		/*
		 * method = fetchExample(introspectedTable, tableName);
		 * addMethodComment(method, "获取记录信息");
		 * method.addAnnotation("@RequestMapping(value = \"query\")");
		 * method.addAnnotation("@ResponseBody");
		 * topLevelClass.addMethod(method);
		 */

		method = fetchByIdExample(introspectedTable, tableName);
		addMethodComment(method, "根据主键获取记录信息");
		method.addAnnotation("@RequestMapping(value = \"queryById\")");
		method.addAnnotation("@ResponseBody");
		topLevelClass.addMethod(method);

		method = queryExample(introspectedTable, tableName);
		addMethodComment(method, "查询记录信息");
		method.addAnnotation("@RequestMapping(value = \"query\")");
		method.addAnnotation("@ResponseBody");
		topLevelClass.addMethod(method);

		method = queryByAll(introspectedTable, tableName);
		addMethodComment(method, "获取所有记录信息");
		method.addAnnotation("@RequestMapping(value = \"queryByAll\")");
		method.addAnnotation("@ResponseBody");
		topLevelClass.addMethod(method);

		// 生成文件
		GeneratedJavaFile file = new GeneratedJavaFile(topLevelClass, project);
		files.add(file);
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method addExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("add" + tableName);
		method.setReturnType(new FullyQualifiedJavaType("Object"));
		if (introspectedTable.getRules().generatePrimaryKeyClass()) {
			method.addParameter(new Parameter(pojoType, "command",
					"@ModelAttribute(\"command\")"));
		} else {
			FullyQualifiedJavaType parameterType;
			if (introspectedTable.getRules().generateBaseRecordClass()) {
				parameterType = new FullyQualifiedJavaType(
						introspectedTable.getBaseRecordType());
			} else {
				parameterType = new FullyQualifiedJavaType(
						introspectedTable.getPrimaryKeyType());
			}
			method.addParameter(new Parameter(pojoType,
					"command", "@ModelAttribute(\"command\")")); //$NON-NLS-1$ //$NON-NLS-2$
		}
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("BaseResp resp = new BaseResp();");
		// method.addBodyLine("resp.setCode(0);");
		// method.addBodyLine("resp.setSuccess(true);");
		method.addBodyLine("try {");

		sb = new StringBuilder();
		sb.append("int result= this.");
		sb.append(getDaoShort());
		sb.append("insert");
		sb.append("(");
		sb.append("command");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("} catch (Exception e) {");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");
		method.addBodyLine("return resp;");
		return method;
	}

	protected Method fetchExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("fetch" + tableName + "s");
		method.setReturnType(new FullyQualifiedJavaType("Object"));

		method.addParameter(new Parameter(qoType,
				"command", "@ModelAttribute(\"command\")")); //$NON-NLS-1$ //$NON-NLS-2$

		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("if (command == null) {");
		method.addBodyLine("command = new " + tableName + "Qo();");
		method.addBodyLine("}");

		sb = new StringBuilder();
		sb.append("PageList<");
		sb.append(tableName + "Po");
		sb.append("> records = (PageList<");
		sb.append(tableName + "Po");
		sb.append(">) ");

		sb.append("this.");
		sb.append(getDaoShort());
		sb.append("query");
		sb.append("(");
		sb.append("command");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("return ResponseUtils.paginationResp(records);");
		return method;
	}

	protected Method queryExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("query");
		method.setReturnType(new FullyQualifiedJavaType("Object"));
		method.addException(FullyQualifiedJavaType
				.getNewRuntimeExceptionInstance());
		method.addParameter(new Parameter(qoType,
				"command", "@ModelAttribute(\"command\")")); //$NON-NLS-1$ //$NON-NLS-2$

		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("BaseResp resp = new BaseResp();");
		method.addBodyLine("if (command == null) {");
		method.addBodyLine("command = new " + tableName + "Qo();");
		method.addBodyLine("}");

		method.addBodyLine("try{");

		sb = new StringBuilder();
		sb.append("PageList<");
		sb.append(tableName + "Po");
		sb.append("> records = (PageList<");
		sb.append(tableName + "Po");
		sb.append(">) ");

		sb.append("this.");
		sb.append(getDaoShort());
		sb.append("query");
		sb.append("(");
		sb.append("command");
		sb.append(");");
		method.addBodyLine(sb.toString());
		method.addBodyLine("return ResponseUtils.paginationResp(records);");
		method.addBodyLine("}catch (Exception e){");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");
		method.addBodyLine("return resp;");
		return method;
	}

	protected Method queryByAll(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("queryByAll");
		method.setReturnType(new FullyQualifiedJavaType("Object"));
		method.addException(FullyQualifiedJavaType
				.getNewRuntimeExceptionInstance());
		method.addParameter(new Parameter(qoType,
				"command", "@ModelAttribute(\"command\")")); //$NON-NLS-1$ //$NON-NLS-2$

		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("BaseResp resp = new BaseResp();");
		method.addBodyLine("if (command == null) {");
		method.addBodyLine("command = new " + tableName + "Qo();");
		method.addBodyLine("}");
		method.addBodyLine("try{");

		sb = new StringBuilder();
		sb.append("List<");
		sb.append(tableName + "Po");
		sb.append("> records =");

		sb.append("this.");
		sb.append(getDaoShort());
		sb.append("queryByAll");
		sb.append("(");
		sb.append("command");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("resp.setData(records);");
		method.addBodyLine("}catch (Exception e){");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");
		method.addBodyLine("return resp;");
		return method;
	}

	protected Method fetchByIdExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("queryById");
		method.setReturnType(new FullyQualifiedJavaType("Object"));
		method.addException(FullyQualifiedJavaType
				.getNewRuntimeExceptionInstance());
		method.addParameter(new Parameter(qoType,
				"command", "@ModelAttribute(\"command\")")); //$NON-NLS-1$ //$NON-NLS-2$

		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();


		method.addBodyLine("BaseResp resp = new BaseResp();");
		method.addBodyLine("try{");

		
		sb = new StringBuilder();
		sb.append(tableName + "Po");
		sb.append(" record = ");

		sb.append("this.");
		sb.append(getDaoShort());
		sb.append("queryById");
		sb.append("(");
		sb.append("command.getId()");
		sb.append(");");
		method.addBodyLine(sb.toString());
		method.addBodyLine("resp.setData(record);");
		method.addBodyLine("}catch (Exception e){");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");

		method.addBodyLine("return resp;");

		return method;
	}

	protected Method batchModifyExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("batchModify");
		method.setReturnType(new FullyQualifiedJavaType("Object"));
		method.addParameter(new Parameter(qoType, "command",
				"@ModelAttribute(\"command\")"));
		method.setVisibility(JavaVisibility.PUBLIC);

		method.addBodyLine("String ids = request.getParameter(\"ids\");");
		StringBuilder sb = new StringBuilder();
		sb = new StringBuilder();
		method.addBodyLine("BaseResp resp = new BaseResp();");
		method.addBodyLine("try {");
		sb.append("this.");
		sb.append(getDaoShort());
		sb.append("batchUpdateByPrimaryKeySelective" + tableName);
		sb.append("(");
		sb.append("CommonUtils.string2Long(ids, \",\"),");
		sb.append("command");
		sb.append(");");
		method.addBodyLine(sb.toString());
		method.addBodyLine("} catch (Exception e) {");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");
		method.addBodyLine("return resp;");
		return method;
	}

	protected Method modifyExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("modify" + tableName);
		method.setReturnType(new FullyQualifiedJavaType("Object"));
		if (introspectedTable.getRules().generatePrimaryKeyClass()) {
			method.addParameter(new Parameter(pojoType, "command",
					"@ModelAttribute(\"command\")"));
		} else {
			FullyQualifiedJavaType parameterType;
			if (introspectedTable.getRules().generateBaseRecordClass()) {
				parameterType = new FullyQualifiedJavaType(
						introspectedTable.getBaseRecordType());
			} else {
				parameterType = new FullyQualifiedJavaType(
						introspectedTable.getPrimaryKeyType());
			}
			method.addParameter(new Parameter(pojoType,
					"command", "@ModelAttribute(\"command\")")); //$NON-NLS-1$ //$NON-NLS-2$
		}
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("BaseResp resp = new BaseResp();");
		// method.addBodyLine("resp.setCode(0);");
		// method.addBodyLine("resp.setSuccess(true);");
		method.addBodyLine("try {");

		sb = new StringBuilder();
		sb.append("int result= this.");
		sb.append(getDaoShort());
		sb.append("updateById");
		sb.append("(");
		sb.append("command");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("} catch (Exception e) {");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");
		method.addBodyLine("return resp;");
		return method;
	}

	protected Method deleteById(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("deleteById");
		method.setReturnType(new FullyQualifiedJavaType("Object"));

		method.addParameter(new Parameter(qoType,
				"command", "@ModelAttribute(\"command\")")); //$NON-NLS-1$ //$NON-NLS-2$

		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("BaseResp resp = new BaseResp();");
		// method.addBodyLine("resp.setCode(0);");
		// method.addBodyLine("resp.setSuccess(true);");
		method.addBodyLine("try {");

		sb = new StringBuilder();
		sb.append("int result= this.");
		sb.append(getDaoShort());
		sb.append("deleteById");
		sb.append("(");
		sb.append("command.getId()");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("} catch (Exception e) {");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");
		method.addBodyLine("return resp;");
		return method;
	}

	protected Method deleteByBatch(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("deleteByBatch");
		method.setReturnType(new FullyQualifiedJavaType("Object"));
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("BaseResp resp = new BaseResp();");
		method.addBodyLine("try {");
		method.addBodyLine("String ids = request.getParameter(\"ids\");");

		sb = new StringBuilder();
		sb.append("int result= this.");
		sb.append(getDaoShort());
		sb.append("deleteByBatch");
		sb.append("(");
		sb.append("ids");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("} catch (Exception e) {");
		method.addBodyLine("error(logger,resp,e);");
		method.addBodyLine("}");
		method.addBodyLine("return resp;");
		return method;
	}

	/**
	 * 添加基础方法
	 * 
	 * @param topLevelClass
	 */
	protected void addBaseMethod(TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable, String tableName) {
		Method method = getSelfBasePath("getSelfBasePath", introspectedTable,
				tableName);
		method.addAnnotation("@Override");
		topLevelClass.addMethod(method);
	}

	/**
	 * 添加字段
	 * 
	 * @param topLevelClass
	 */
	protected void addField(TopLevelClass topLevelClass, String tableName) {
		// 添加 dao
		Field field = new Field();
		field.setName(serviceName); // 设置变量名
		topLevelClass.addImportedType(interfaceType);
		field.setType(interfaceType); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		if (enableAnnotation) {
			field.addAnnotation("@Autowired");
		}
		topLevelClass.addField(field);
	}

	/**
	 * 基础方法
	 * 
	 */
	protected Method getSelfBasePath(String methodName,
			IntrospectedTable introspectedTable, String tableName) {
		Method method = new Method();
		method.setName(methodName);
		method.setReturnType(new FullyQualifiedJavaType("String"));
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();
		sb.append("return \"/\";");
		method.addBodyLine(sb.toString());
		return method;
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method getOtherInsertboolean(String methodName,
			IntrospectedTable introspectedTable, String tableName) {
		Method method = new Method();
		method.setName(methodName);
		method.setReturnType(returnType);
		method.addParameter(new Parameter(pojoType, "record"));
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();
		if (returnType == null) {
			sb.append("this.");
		} else {
			sb.append("return this.");
		}
		sb.append(getServiceShort());
		sb.append(methodName);
		sb.append("(");
		sb.append("record");
		sb.append(");");
		method.addBodyLine(sb.toString());
		return method;
	}

	protected void addComment(JavaElement field, String comment) {
		StringBuilder sb = new StringBuilder();
		field.addJavaDocLine("/**");
		sb.append(" * ");
		comment = comment.replaceAll(OutputUtilities.lineSeparator, "<br>"
				+ OutputUtilities.lineSeparator + "\t * ");
		sb.append(comment);
		field.addJavaDocLine(sb.toString());
		field.addJavaDocLine(" */");
	}

	/**
	 * 添加字段
	 * 
	 * @param topLevelClass
	 */
	protected void addField(TopLevelClass topLevelClass) {
		// 添加 success
		Field field = new Field();
		field.setName("success"); // 设置变量名
		field.setType(FullyQualifiedJavaType.getBooleanPrimitiveInstance()); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		addComment(field, "执行结果");
		topLevelClass.addField(field);
		// 设置结果
		field = new Field();
		field.setName("message"); // 设置变量名
		field.setType(FullyQualifiedJavaType.getStringInstance()); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		addComment(field, "消息结果");
		topLevelClass.addField(field);
	}

	/**
	 * 添加方法
	 * 
	 */
	protected void addMethod(TopLevelClass topLevelClass) {
		Method method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setName("setSuccess");
		method.addParameter(new Parameter(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance(), "success"));
		method.addBodyLine("this.success = success;");
		topLevelClass.addMethod(method);

		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setReturnType(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance());
		method.setName("isSuccess");
		method.addBodyLine("return success;");
		topLevelClass.addMethod(method);

		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setName("setMessage");
		method.addParameter(new Parameter(FullyQualifiedJavaType
				.getStringInstance(), "message"));
		method.addBodyLine("this.message = message;");
		topLevelClass.addMethod(method);

		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setReturnType(FullyQualifiedJavaType.getStringInstance());
		method.setName("getMessage");
		method.addBodyLine("return message;");
		topLevelClass.addMethod(method);
	}

	/**
	 * 添加方法
	 * 
	 */
	protected void addMethod(TopLevelClass topLevelClass, String tableName) {
		Method method2 = new Method();
		for (int i = 0; i < methods.size(); i++) {
			Method method = new Method();
			method2 = methods.get(i);
			method = method2;
			method.removeAllBodyLines();
			method.removeAnnotation();
			StringBuilder sb = new StringBuilder();
			sb.append("return this.");
			sb.append(getServiceShort());
			sb.append(method.getName());
			sb.append("(");
			List<Parameter> list = method.getParameters();
			for (int j = 0; j < list.size(); j++) {
				sb.append(list.get(j).getName());
				sb.append(",");
			}
			sb.setLength(sb.length() - 1);
			sb.append(");");
			method.addBodyLine(sb.toString());
			topLevelClass.addMethod(method);
		}
		methods.clear();
	}

	/**
	 * BaseUsers to baseUsers
	 * 
	 * @param tableName
	 * @return
	 */
	protected String toLowerCase(String tableName) {
		StringBuilder sb = new StringBuilder(tableName);
		sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
		return sb.toString();
	}

	/**
	 * BaseUsers to baseUsers
	 * 
	 * @param tableName
	 * @return
	 */
	protected String toUpperCase(String tableName) {
		StringBuilder sb = new StringBuilder(tableName);
		sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
		return sb.toString();
	}

	/**
	 * 导入需要的类
	 */
	private void addImport(TopLevelClass topLevelClass) {
		// topLevelClass.addImportedType(boType);
		topLevelClass.addImportedType(qoType);
		topLevelClass.addImportedType(pojoType);
		topLevelClass.addImportedType(listType);
		topLevelClass.addImportedType(slf4jLogger);
		topLevelClass.addImportedType(slf4jLoggerFactory);
		topLevelClass.addImportedType(abstractController);
		topLevelClass.addImportedType(baseResp);
		topLevelClass.addImportedType(pageList);
		topLevelClass.addImportedType(autowired);
		topLevelClass.addImportedType(responseUtils);
		topLevelClass.addImportedType(commonUtil);
		//topLevelClass.addImportedType(paginationResp);
		//topLevelClass.addImportedType(paginator);

	}

	/**
	 * 导入logger
	 */
	private void addLogger(TopLevelClass topLevelClass) {
		Field field = new Field();
		field.setFinal(true);
		field.setInitializationString("LoggerFactory.getLogger("
				+ topLevelClass.getType().getShortName() + ".class)"); // 设置值
		field.setName("logger"); // 设置变量名
		field.setStatic(true);
		field.setType(new FullyQualifiedJavaType("Logger")); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		topLevelClass.addField(field);
	}

	private String getServiceShort() {
		return toLowerCase(serviceName) + ".";
	}

	public boolean clientInsertMethodGenerated(Method method,
			Interface interfaze, IntrospectedTable introspectedTable) {
		returnType = method.getReturnType();
		return true;
	}

	public void addMethodComment(Method method, String comments) {

		StringBuilder sb = new StringBuilder();
		String remark = comments;
		if (remark != null && remark.length() != 0) {
			method.addJavaDocLine("/**"); //$NON-NLS-1$
			sb.append(" * "); //$NON-NLS-1$
			remark = remark.replaceAll(OutputUtilities.lineSeparator, "<br>"
					+ OutputUtilities.lineSeparator + "\t * ");
			sb.append(remark);
			method.addJavaDocLine(sb.toString());
			method.addJavaDocLine(" */"); //$NON-NLS-1$
		}
	}

	private String getDaoShort() {
		return toLowerCase(interfaceType.getShortName()) + ".";
	}

	public void addMethodAnnotation(Method method) {
		method.addAnnotation("@Transactional()");
	}

	@Override
	public List<GeneratedJavaScriptFile> contextGenerateAdditionalJavaScriptFiles() {
		// TODO Auto-generated method stub
		List<GeneratedJavaScriptFile> files = new ArrayList<GeneratedJavaScriptFile>(
				1);
		return files;
	}

	@Override
	public List<GeneratedJavaScriptFile> contextGenerateAdditionalJavaScriptFiles(
			IntrospectedTable introspectedTable) {
		List<GeneratedJavaScriptFile> files = new ArrayList<GeneratedJavaScriptFile>(
				1);
		return files;
	}
}
